const express = require("express");
const jwt = require("jsonwebtoken");
const User = require("@models/user");
const bcrypt = require("bcrypt");
const transporter = require("@utils/email");
const router = express.Router();

const SECRET_KEY = process.env.SECRET_KEY; // 建议用环境变量
const REFRESH_SECRET_KEY = process.env.REFRESH_SECRET_KEY || "refresh-secret-key"; // 刷新令牌密钥

// 添加刷新锁
let isRefreshing = false;
let refreshSubscribers = [];

// 添加订阅者函数
function subscribeTokenRefresh(cb) {
  refreshSubscribers.push(cb);
}

// 执行所有订阅者
function onRefreshed(token) {
  refreshSubscribers.forEach(cb => cb(token));
  refreshSubscribers = [];
}

// 登录接口
router.post("/login", async (req, res) => {
  const { username, password } = req.body;
  try {
    const user = await User.findOne({ username });
    if (user && (await bcrypt.compare(password, user.password))) {
      // 登录成功，生成 token
      const accessToken = jwt.sign(
        { id: user._id, username: user.username },
        SECRET_KEY,
        { expiresIn: "30m" } // 访问令牌短期有效
      );
      
      // 生成刷新令牌，有效期更长
      const refreshToken = jwt.sign(
        { id: user._id },
        REFRESH_SECRET_KEY,
        { expiresIn: "7d" }
      );
      
      // 保存刷新令牌到用户记录中
      user.refreshToken = refreshToken;
      await user.save();
      
      res
        .status(200)
        .json({ 
          success: true, 
          message: "登录成功", 
          data: { 
            accessToken,
            refreshToken 
          } 
        });
    } else {
      res.status(200).json({ success: false, message: "用户名或密码错误" });
    }
  } catch (err) {
    res.status(500).json({ success: false, message: err.message });
  }
});

// 刷新令牌接口
router.post("/refresh-token", async (req, res) => {
  const { refreshToken } = req.body;
  
  if (!refreshToken) {
    return res.status(401).json({ success: false, message: "未提供刷新令牌" });
  }
  
  try {
    // 验证刷新令牌
    const decoded = jwt.verify(refreshToken, REFRESH_SECRET_KEY);
    
    // 查找用户并验证刷新令牌是否匹配
    const user = await User.findById(decoded.id);
    
    if (!user || user.refreshToken !== refreshToken) {
      return res.status(401).json({ success: false, message: "无效的刷新令牌" });
    }
    
    // 生成新的访问令牌
    const newAccessToken = jwt.sign(
      { id: user._id, username: user.username },
      SECRET_KEY,
      { expiresIn: "30m" }
    );
    
    // 可选：生成新的刷新令牌（轮换策略）
    const newRefreshToken = jwt.sign(
      { id: user._id },
      REFRESH_SECRET_KEY,
      { expiresIn: "7d" }
    );
    
    // 更新用户的刷新令牌
    user.refreshToken = newRefreshToken;
    await user.save();
    
    res.status(200).json({
      success: true,
      data: {
        accessToken: newAccessToken,
        refreshToken: newRefreshToken
      }
    });
    
  } catch (error) {
    if (error.name === "TokenExpiredError") {
      return res.status(401).json({ success: false, message: "刷新令牌已过期，请重新登录" });
    }
    res.status(500).json({ success: false, message: "服务器错误" });
  }
});

router.post("/register", async (req, res) => {
  const { username, password, email } = req.body;

  // 1. 参数校验
  if (!username || !password || !email) {
    return res
      .status(200)
      .json({ success: false, message: "用户名和密码和邮箱不能为空" });
  }

  // 2. 检查用户名是否已存在
  const exist = await User.findOne({ username });
  if (exist) {
    return res.status(200).json({ success: false, message: "用户名已存在" });
  }

  // 3. 密码加密
  const hash = await bcrypt.hash(password, 10);

  // 4. 存入数据库
  const user = new User({ username, password: hash, email });
  await user.save();

  // 5. 返回结果
  res.json({ success: true, message: "注册成功" });
});
// 获取验证码
router.post("/forgot-password", async (req, res) => {
  const { email } = req.body;
  try {
    const user = await User.findOne({ email });
    if (!user)
      return res.status(200).json({ success: false, message: "邮箱未注册" });

    // 生成验证码
    const code = Math.floor(1000 + Math.random() * 9000);
    user.checkCode = code;
    user.checkCodeExpire = Date.now() + 30 * 60 * 1000; // 30分钟
    await user.save();

    // 发送邮件
    // 用 nodemailer 发送 resetUrl 到用户邮箱
    const mailOptions = {
      from: '"laiweiguo" <laiweiguo2025@163.com>', // 发件人
      to: email, // 收件人
      subject: "重置密码", // 主题
      text: "下面是验证码三十分钟内容有效", // 纯文本内容
      html: `<b>${code}</b>下面是验证码三十分钟内容有效`, // HTML内容
    };
    transporter.sendMail(mailOptions, (error, info) => {
      if (error) {
        res.status(200).json({ success: false, message: error });
        return console.log(error);
      }
      res.status(200).json({ success: true, message: "重置邮件已发送" });
    });
  } catch (error) {
    // 真正的服务器错误才返回 500
    res.status(500).json({
      success: false,
      message: "服务器错误",
    });
  }
});

router.post("/reset-password", async (req, res) => {
  try {
    const { checkCode, newPassword, email } = req.body;

    if (!checkCode || !newPassword || !email) {
      return res.status(200).json({
        success: false,
        message: "验证码、新密码和邮箱都不能为空",
      });
    }

    // 清理验证码（去除空格并转换为字符串）
    const sanitizedCode = String(checkCode).trim();

    // 先查找用户
    const user = await User.findOne({ email });

    if (!user) {
      return res.status(200).json({
        success: false,
        message: "邮箱不存在",
      });
    }

    // 验证码为空或已被使用
    if (!user.checkCode) {
      return res.status(200).json({
        success: false,
        message: "验证码无效或已被使用",
      });
    }

    // 检查验证码是否正确
    if (user.checkCode !== sanitizedCode) {
      return res.status(200).json({
        success: false,
        message: "验证码错误",
      });
    }

    // 检查是否过期
    if (!user.checkCodeExpire || user.checkCodeExpire < Date.now()) {
      return res.status(200).json({
        success: false,
        message: "验证码已过期",
      });
    }

    user.password = await bcrypt.hash(newPassword, 10);
    user.checkCode = "";
    user.checkCodeExpire = "";
    await user.save();

    res.status(200).json({ success: true, message: "重置密码成功" });
  } catch (error) {
    // 只有服务器错误才返回 500
    res.status(500).json({
      success: false,
      message: "服务器错误",
    });
  }
});

// 登出时撤销令牌
router.post("/logout", async (req, res) => {
  const { refreshToken } = req.body;
  
  // 将refreshToken加入黑名单
  await TokenBlacklist.create({ token: refreshToken });
  
  // 清除用户的refreshToken
  const user = await User.findById(req.user.id);
  user.refreshToken = "";
  await user.save();
  
  res.status(200).json({ success: true, message: "登出成功" });
});

// 验证时检查黑名单
const isBlacklisted = await TokenBlacklist.findOne({ token: refreshToken });
if (isBlacklisted) {
  return res.status(401).json({ message: "令牌已被撤销" });
}
module.exports = router;
